package com.example.smartcitydemo.repo.subway

import androidx.recyclerview.widget.DiffUtil
import com.example.smartcity_jscs.network.ResultStates.Resource
import com.example.smartcitydemo.MyApplication
import com.example.smartcitydemo.base.BaseRepo
import com.example.smartcitydemo.bean.*
import com.example.smartcitydemo.exception.AppExcpetion
import com.example.smartcitydemo.exception.ErrorType
import com.example.smartcitydemo.network.client.noAuthApiService
import com.example.smartcitydemo.viewModel.SubwayViewModel.SubWayDetailTransform
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn

/**
 * @PACKAGE_NAME: com.example.smartcitydemo.repo.subway
 * @NAME: Caleb.F
 * @DATE: 2021/11/14 21:47
 * @Email: 1919796283@qq.com
 */
data class SubwayStartDetailRequestBean(
    val stationName: String,
    val stationIdList: List<String>
)


data class SubWayStartEndResultBean(
    val titleString: String,
    val subStartDataFirst: LineDetail,
    val subStartDataSecond: LineDetail
) {
    companion object diffCallBack : DiffUtil.ItemCallback<SubWayStartEndResultBean>() {
        override fun areItemsTheSame(
            oldItem: SubWayStartEndResultBean,
            newItem: SubWayStartEndResultBean
        ): Boolean {
            return oldItem.titleString == newItem.titleString
        }

        override fun areContentsTheSame(
            oldItem: SubWayStartEndResultBean,
            newItem: SubWayStartEndResultBean
        ): Boolean {
            return oldItem.subStartDataFirst.name == newItem.subStartDataFirst.name
        }


    }
}

object SubwayRepo : BaseRepo() {
    suspend fun getSubWayHomeBanner(): Flow<Resource<List<String>>> {
        return requestListData({
            noAuthApiService.getSubWayHomeBanner()
        }, {
            it.map {
                it.advImg
            }
        })
    }

    suspend fun getLoactionInfo(): Flow<Resource<String>> {
        return request({ noAuthApiService.getLocation() }, {
            "${it.province}${it.area}${it.city}${it.location}"
        })
    }


    suspend fun getTodayWeatherInfo(): Flow<Resource<WeatherInfo>> {
        return request({ noAuthApiService.getTodayWeatherInfo() }, { it })
    }


    suspend fun getLineData(): Flow<Resource<List<LineDataBean>>> {
        return request({ noAuthApiService.getLineInfo() }, {
            it.distinctBy { it.lineName }.sortedBy {
                it.sortedName
            }
        })
    }

    suspend fun getStationFull(): Flow<Resource<List<StationDataBean>>> {
        return request({ noAuthApiService.getFullStationList() }, { it1 ->
            it1.sortedBy {
                it.initialsOfStationNames
            }
        })
    }

    /**
     * 获取具体线路的数据
     * @param lineId String 线路id
     */
    suspend fun getStationList(lineId: String): Flow<Resource<List<StationDataBean>>> {
        return request({ noAuthApiService.getStationList(Integer.parseInt(lineId)) }, { it1 ->
            it1.sortedBy {
                it.initialsOfStationNames
            }
        })
    }
    /*
    * 获取线路的详情页
    */
    suspend fun getStationDetailInfo(subWayDetailTransform: SubWayDetailTransform): Flow<Resource<SubWayStartDetail>> {
        return request({
            noAuthApiService.getStartEndInfo(
                subWayDetailTransform.lineName,
                subWayDetailTransform.lineIds
            )
        }) { it }
    }

    /**
     * 获取线路起点、终点信息
     */
    suspend fun getStartStationList(startDetailRequest: SubwayStartDetailRequestBean)
            : Flow<Resource<List<SubWayStartEndResultBean>>> {
        val joinToString = startDetailRequest.stationIdList.joinToString(",")
        return request({
            noAuthApiService.getStartEndInfo(
                startDetailRequest.stationName,
                joinToString
            )
        }, { bean ->
            val mutableStationList = mutableListOf<SubWayStartEndResultBean>()
            val map = bean.lineList.groupBy(keySelector = { lineDetail ->
                lineDetail.name
            })
            //接口目前的数据是成对出现，一个线路id对应两组数据
            map.onEach {
                mutableStationList.add(
                    SubWayStartEndResultBean(
                        "${bean.stepInfo.name}${it.key}",
                        it.value[0], it.value[1]
                    )
                )
            }
            mutableStationList
        })
    }

    /**
     * 请求图片连接
     * @return Flow<Resource<String>>
     */
    suspend fun getSubWayImage(): Flow<Resource<SubWayImage>> {
        return request({ noAuthApiService.getStationImage() }, {
            it
        })
    }

    suspend fun getSubWayHomeDataDetail(currrentStation: String): Flow<Resource<List<CurrentStationDetail>>> {
        return request({ noAuthApiService.getCurrentStation(currrentStation) }, {
            it
        })
    }

    /**
     * 获取随机站点
     */
    suspend fun getStationNameAtRandom(): Flow<Resource<String>> {
        return flow {
            val netRequestResult = noAuthApiService.getFullStationList()
            if (netRequestResult.code == 200) {
                if (netRequestResult.data == null) {
                    throw AppExcpetion(
                        ErrorType.NO_CONTENT_ERROR,
                        RuntimeException(ErrorType.NO_CONTENT_ERROR.msg)
                    )
                } else {
                    val data = netRequestResult.data
                    val number = (data.indices)
                    while (true) {
                        val random = number.random()
                        emit(Resource.Success(data[random].name))
                        delay(10000)
                    }
                }
            } else {
                handleResponseErrorCode(netRequestResult.code, netRequestResult.msg)
            }
        }.flowOn(Dispatchers.IO)

    }

    /**
     * 地铁公告
     * @return Flow<Resource<List<SubWayNoticeBean>>>
     */
    suspend fun getSubWayNotice(): Flow<Resource<List<SubWayNoticeBean>>> {
        return requestListData({ noAuthApiService.getSubWayNewsList() }, { it })
    }

    /**
     * 获取乘客通知
     * @return Flow<Resource<SubWayPassengerNotice>>
     */
    suspend fun getSubWayBroadCastFirst(): Flow<Resource<SubWayPassengerNotice>> {
        return request({ noAuthApiService.getBroadMessage(1) }, {
            it
        }
        )
    }


}